package com.pxmeta.order.service.impl;

import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.diagnosis.DiagnosisUtils;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeFastpayRefundQueryModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.pxmeta.common.constant.Status;
import com.pxmeta.common.exception.ServiceException;
import com.pxmeta.common.utils.CreateSignUtil;
import com.pxmeta.common.utils.StringUtils;
import com.pxmeta.order.entity.Order;
import com.pxmeta.order.enums.OrderStatusEnum;
import com.pxmeta.order.mapper.OrderMapper;
import com.pxmeta.order.service.IOrderPayService;
import com.pxmeta.order.service.IOrderService;
import com.pxmeta.order.vo.AlipayCreateOrderVO;
import com.pxmeta.order.vo.CreateOrderVO;
import com.pxmeta.product.entity.Product;
import com.pxmeta.product.enums.ProductTypeEnum;
import com.pxmeta.product.service.IProductService;
import com.pxmeta.user.entity.*;
import com.pxmeta.user.entity.vo.UserRechargeVO;
import com.pxmeta.user.service.IUserBillService;
import com.pxmeta.user.service.IUserService;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Wrapper;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;

@Service
@Slf4j
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {


    private final IOrderPayService orderPayService;

    private final IProductService productService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IUserBillService userBillService;


    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public CreateOrderVO createOrder(Long userId, Long productId, String appStoreProductId, Integer type) {

        Product product = null;
        if (StringUtils.isNotBlank(appStoreProductId)){
            product = productService.getByAppStoreId(appStoreProductId);
        }else {
            product = productService.getById(productId);
        }

        if (null == product){
            throw new ServiceException("商品不存在或已下架！");
        }
        BigDecimal realPrice = product.getRealPrice().setScale(2, RoundingMode.HALF_UP);
        Order order = new Order();
        String orderNo = IdWorker.getMillisecond();
        order.setOrderNo(orderNo);
        order.setStatus(OrderStatusEnum.UNPAID.getStatus());
        order.setProductId(productId);
        order.setAppStoreProductId(appStoreProductId);
        order.setUserId(userId);
        order.setTotalPrice(realPrice);
        this.save(order);
        //生成预付款单号
        return orderPayService.prepay(realPrice, orderNo, product.getDescription());
    }

    @Override
    @SneakyThrows
    @Transactional(rollbackFor = ServiceException.class)
    public AlipayCreateOrderVO createOrderByAlipay(Long userId, Long productId) {
        Product product = productService.getById(productId);

        if (null == product){
            throw new ServiceException("商品不存在或已下架！");
        }
        String orderNo = IdWorker.getMillisecond();
        BigDecimal realPrice = product.getRealPrice().setScale(2, RoundingMode.HALF_UP);


        Order order = new Order();
        order.setOrderNo(orderNo);
        order.setStatus(OrderStatusEnum.UNPAID.getStatus());
        order.setProductId(productId);
        order.setType("alipay");
        order.setUserId(userId);
        order.setTotalPrice(realPrice);
        this.save(order);

        String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCnNP/dLzOcYV0KYnyPxP9p2tyFJffSwZ/2co4YEE09m1ZZ/vcYxG7HWkmbKkMpRuNwOhoHFlIJMjmr/oGhQewsZnbTEgapyHGYpcPVsB60+g9SwF5ppadKm+FvgSxnR9zPYF7oaUAG1pBL/EQoxuNw2SKY8cNkoxsXrCD7bJQmKRlAKH5Oa4CUD8AbTSZCXxRrh7Yj7ItWw4aAtLGhl5RxHv/UyfmgXpJd0NxT87qr7hDNg5VX9hz7ulODhAjMAEv7Q96UKQWBU5z2OKSBfRPUYaNCrQrWYRrrMPb2ppKHtf7041Q/ET1fFID1cscJnEltV+SjjQS08fxz5Ri4i15nAgMBAAECggEAZGz+qBgrhWcs/Im+ipMlXKyo+ged2yWUL+8JzQYtfi0IJjFus593caCWyO0PPYFoJQWgkFUlnIRgAx9vOC1h7iD0iT0wZ1UOdUJKZtPK/aObBHapvgZSfgs10UTiKH4O7zbQigJ9BB5muFyhi2Q5QpQHpZi/ZHhaU1N808WZDXl0hAmzgLpz631lynKTbxkfBPmE3BULWHLK7S3btW1VpCU9gpwovAGzOUtU0sVm8euk8zCmAttf1XfZe73R+gkn0w2o5lZlIXtzhuCLdILBL4UQRIOAa9shOIe0ZHyPPjtLIskQ4+hiazXfUI8z8uFx0Z2j5PapRJi0IHo0ei7xcQKBgQDfPFhIVrFXHl/KULYDElpmgzxC4wXrMcK3zIpsOyRujiQZfIaWh8CjZSjtM7bJx4OgB+iC8LMTs/aILFDkYaYOfG5IP/wnT3pnPtNqPbwk/0/GmHnnRpM6FBRviDZJB2Adytiowx9alu1uuyfCu41j88v2oXIBFFGhq53QRwOnvQKBgQC/v3vSQzxgIWdEHD+3C6v7CoONcK2NcW8kDxhhSvii/vC+QbkzM5rHFX1sxwSy0zP8T4N38WEQ5bDIwTpqTjXBUyVFcslTQ0L+Nh0crcayfSaSPSWKPzMpEq38TWFlM7siQMpZm9teKQsaCtn3MV4ezgicB/6KEID51HowIUce8wKBgCWg/2SaMGR1+0GYH0YfRtu2zWac6/d8OM1Qjhi2U2rLTOx64BjpoyAnwiFRsUML/XTxQFEqD5WHpUvI5I3Ko/oXIWPOXUunCwPyRCLJazh1TNY2B35jmBeXIOa3+CaRNrNu6Nxxn4xemoEqzQX3JVsu0jeteRETgrsUuZJNFiGlAoGAWrMgxty2+mHSjw0ttk/3EdBvWcAq1/UINW5OgfcMlU0yY0yDZgzK8dDge0vIlS4CMR8LePjciTmc3dlI4HAOTVwfDTK2uIPgdI70RlSM4HEChboWv8YVVSBY3DdeEpjds94h2TE4GtofPjpTz/GyK7AZsnS1mmkkGQjAo3OaSLECgYEAmBgGOLmKw4VMBA1g/X3XdIUaOUJnafXpZ+4Q5mnI81oCn5vG51JD+kclv1VzO9nA/Q5PfLPQYlRbbaQKsJSO1uGBnlYmlJ4DpoFz5PTHKGenVAmHpAWfjISLQAXBJHw1URLJGcwR8vhvXYZChoZ9PfenGOMwg/WU9ieE03GsYYI=";
        String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnPShBeABn+b+aEsS3euH576Zn79ZR3uEeHQR7bUlm/LUcVjYRT7OTw2m2s47+gdiZPfGpoV+5dtoyE1nPIUXcvngc57uHBGeLbsWcDsRogYCJ+aiRTRBbmwBVEhYQbkOyb8szmdm44DQQfl7Kga3zqAgshfxwr1ihNgLSTwT17mlHd+tUq/X4w5a7XTb0HV1bu5d5yPrnahPhpuCFFEphBNuFBjA3s4z9+lQSX/SBlkqLP80gNlM2eTV47XRbbm8DGDPjV5sHHbYT0OSW7jPLvMDprEghx0cFoz7q+F3MituYHYLLnzfQBsXtjJAothk/rVDNmak36c8ekw+1AJUywIDAQAB";
        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
        alipayConfig.setAppId("2021004130615029");
        alipayConfig.setPrivateKey(privateKey);
        alipayConfig.setFormat("json");
        alipayConfig.setAlipayPublicKey(alipayPublicKey);
        alipayConfig.setCharset("UTF-8");
        alipayConfig.setSignType("RSA2");
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setOutTradeNo(orderNo);
        model.setTotalAmount(realPrice.doubleValue()+"");
        model.setSubject("碰心币");
        request.setBizModel(model);
        request.setNotifyUrl("https://api.pengxinmeta.com/api/order/alipayNotify");
        AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
        System.out.println(response.getBody());
        if (response.isSuccess()) {
            AlipayCreateOrderVO vo = new AlipayCreateOrderVO();
            vo.setOrderInfo(response.getBody());
            return vo;
        } else {
             String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            throw new ServiceException("接口调用失败，错误信息："+diagnosisUrl);
        }

    }

    @Override
    public CreateOrderVO createOrder(Long userId, Long productId, String appStoreProductId, String openId) {
        Product product = null;
        if (StringUtils.isNotBlank(appStoreProductId)){
            product = productService.getByAppStoreId(appStoreProductId);
        }else {
            product = productService.getById(productId);
        }

        if (null == product){
            throw new ServiceException("商品不存在或已下架！");
        }
        BigDecimal realPrice = product.getRealPrice().setScale(2, RoundingMode.HALF_UP);
        Order order = new Order();
        String orderNo = IdWorker.getMillisecond();
        order.setOrderNo(orderNo);
        order.setStatus(OrderStatusEnum.UNPAID.getStatus());
        order.setProductId(productId);
        order.setAppStoreProductId(appStoreProductId);
        order.setUserId(userId);
        order.setTotalPrice(realPrice);
        this.save(order);
        //生成预付款单号
        return orderPayService.prepayByJsapi(openId, realPrice, orderNo, product.getDescription());
    }

    @Override
    public CreateOrderVO createOrder(Long userId, Integer number,  String openId) {
        BigDecimal realPrice = BigDecimal.valueOf(number/100).setScale(2, RoundingMode.HALF_UP);
        Order order = new Order();
        String orderNo = IdWorker.getMillisecond();
        order.setOrderNo(orderNo);
        order.setStatus(OrderStatusEnum.UNPAID.getStatus());
        order.setProductId(null);
        order.setAppStoreProductId(null);
        order.setUserId(userId);
        order.setTotalPrice(realPrice);
        this.save(order);
        //生成预付款单号
        return orderPayService.prepayByJsapi(openId,realPrice, orderNo, "碰心币");
    }


    /**
     * 检查 appStore 是否已完成交易
     * @param transactionId
     * @return
     */
    private boolean checkAppStoreTransaction(String transactionId){
        LambdaQueryWrapper<Order> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Order::getTransactionId, transactionId);
        Order one = this.getOne(wrapper, false);
        return one != null;
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void paySuccess(String orderNo,String transactionId, String receipt,String payType) {

        Order order = this.getByOrderNo(orderNo);
        order.setType(payType);
        if (this.checkAppStoreTransaction(transactionId)){
            return;
        }

        if (OrderStatusEnum.COMPLETED.getStatus().equals(order.getStatus())){
            throw new ServiceException("订单状态已完成");
        }

        //标记已完成
        order.setStatus(OrderStatusEnum.COMPLETED.getStatus());
        order.setTransactionId(transactionId);
        order.setReceipt(receipt);
        Long productId = order.getProductId();
        String appStoreProductId = order.getAppStoreProductId();
        Product product;
        if (StringUtils.isNotBlank(appStoreProductId)){
            product = productService.getByAppStoreId(appStoreProductId);
        }else {
            product = productService.getById(productId);
        }
        //更新订单状态
        this.updateById(order);
        BigDecimal count = BigDecimal.ZERO;

        if (productId != null){
            //金币数
            count = product.getCount();
            if (StringUtils.isNotBlank(transactionId)){
                count = product.getAppleCount();
            }
        }else {
            count = BigDecimal.valueOf(order.getTotalPrice().doubleValue()*100);
        }




        //虚拟币，记录流水，并累加用户金币额度
        if (productId == null || ProductTypeEnum.VIRTUAL_CURRENCY.getType().equals(product.getType())){
            User user = userService.getById(order.getUserId());
            BigDecimal balance = user.getBalance();

            BigDecimal finalBalance = balance.add(count).setScale(2, RoundingMode.HALF_UP);
            User updateUser = new User();
            updateUser.setId(user.getId());
            updateUser.setBalance(finalBalance);
            userService.updateById(updateUser);

            //记录流水表
            UserBill userBill = new UserBill();
            userBill.setDescription(String.format("碰心币充值成功，数量：%s个", count));
            userBill.setUserId(order.getUserId());
            userBill.setTargetId(order.getUserId());
            userBill.setCategory(UserBillCategoryEnum.BALANCE.getCategory());
            userBill.setPm(1);
            userBill.setNumber(count.setScale(2,RoundingMode.HALF_UP));
            userBill.setType(UserBillTypeEnum.RECHARGE.getType());
            userBill.setStatus(Status.SUCCESS.getValue());
            userBillService.save(userBill);


            Long parentUserId = user.getParentUserId();
            //如果注册小于30天，且有上级。则会记录给上级 8%充值分成。
            LocalDateTime createTime = user.getCreateTime();
            long days = Duration.between(createTime, LocalDateTime.now()).toDays();
//            if (parentUserId !=null && days<=30){
//                log.info("用户：{}，首次充值完成",user.getNickname());
//                //如果是首次充值，立刻返陪陪20收益。
////                Boolean isFirst = this.checkFirstRecharge(order.getUserId());
//                BigDecimal number = order.getTotalPrice().multiply(BigDecimal.valueOf(0.08)).setScale(2, RoundingMode.HALF_UP);
//
////                if (isFirst){
////                    number = number.add(BigDecimal.valueOf(10));
////                    userService.addBalance(user.getId(),BigDecimal.valueOf(2000));
////                }
//                userService.increaseProfit(parentUserId,number);
//                UserBill shareBill = new UserBill();
//                shareBill.setDescription(String.format("下级充值返现：%s", number));
//                shareBill.setUserId(parentUserId);
//                shareBill.setTargetId(order.getUserId());
//                shareBill.setCategory(UserBillCategoryEnum.PROFIT.getCategory());
//                shareBill.setPm(1);
//                shareBill.setNumber(number);
//                shareBill.setType(UserBillTypeEnum.SHARE.getType());
//                shareBill.setStatus(Status.SUCCESS.getValue());
//                userBillService.save(shareBill);
//            }
        }


    }

    public static void main(String[] args) {
        BigDecimal number = BigDecimal.valueOf(0.48);
        number = number.add(BigDecimal.valueOf(20));
        System.out.println(number);
    }

    private Boolean checkFirstRecharge(Long userId) {
        LambdaQueryWrapper<Order> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Order::getUserId,userId)
                .eq(Order::getStatus, OrderStatusEnum.COMPLETED.getStatus());
        List<Order> list = this.list(wrapper);
        return list.size()==1;
    }


    @Override
    public Order getByOrderNo(String orderNo) {
        LambdaQueryWrapper<Order> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Order::getOrderNo, orderNo);
        return this.getOne(wrapper);
    }

    @Override
    public Integer getOrderStatus(Long userId, Long serviceId) {
        LambdaQueryWrapper<Order> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Order::getUserId, userId)
                .eq(Order::getProductId,serviceId)
                .ne(Order::getStatus,2);
        Order order = this.getOne(wrapper);
        return order == null?-1:order.getStatus();
    }

    @Override
    public Double getTotalRecharge(Long userId) {

        LambdaQueryWrapper<Order> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Order::getUserId, userId)
                .eq(Order::getStatus, Status.SUCCESS.getValue());
        List<Order> totalOrder = this.list(wrapper);//總訂單

        double totalPrice = 0d;
        for (Order order : totalOrder) {
            totalPrice += order.getTotalPrice().doubleValue();
        }
        return totalPrice;
    }


    @Override
    public Double getTotalRecharge(String keyword, Integer status, String startTime, String endTime) {

        LambdaQueryWrapper<Order> wrapper = Wrappers.lambdaQuery();
//        wrapper.eq(Order::getStatus, Status.SUCCESS.getValue());

        if (StringUtils.isNotBlank(keyword)){
            User user = userService.getByAccount(keyword);
            wrapper.eq(Order::getUserId, user.getId());
        }
        if (StringUtils.isNotBlank(startTime)){
            wrapper.ge(Order::getCreateTime, startTime)
                    .le(Order::getCreateTime, endTime);
        }

        if (status != null){
            wrapper.eq(Order::getStatus, status);
        }
        List<Order> totalOrder = this.list(wrapper);//總訂單

        double totalPrice = 0d;
        for (Order order : totalOrder) {
            totalPrice += order.getTotalPrice().doubleValue();
        }
        return BigDecimal.valueOf(totalPrice).setScale(2, RoundingMode.HALF_UP).doubleValue();
    }

    @Override
    public Double getTotalRecharge(List<Long> userIds) {
        LambdaQueryWrapper<Order> wrapper = Wrappers.lambdaQuery();

        if (userIds.isEmpty()){
            return 0d;
        }
        wrapper.in(Order::getUserId, userIds)
                .gt(Order::getTotalPrice,0)
                .eq(Order::getStatus, Status.SUCCESS.getValue());
        List<Order> totalOrder = this.list(wrapper);
        double totalPrice = 0d;
        for (Order order : totalOrder) {
            totalPrice += order.getTotalPrice().doubleValue();
        }

        return totalPrice;
    }

    @Override
    public IPage<UserRechargeVO> getRechargeList(Integer page, Integer size, String keyword,Integer status, String startTime, String endTime) {
        LambdaQueryWrapper<Order> wrapper = Wrappers.lambdaQuery();
        if (StringUtils.isNotBlank(keyword)){
            User user = userService.getByAccount(keyword);
            wrapper.eq(Order::getUserId, user.getId());
        }
        if (StringUtils.isNotBlank(startTime)){
            wrapper.ge(Order::getCreateTime, startTime)
                    .le(Order::getCreateTime, endTime);
        }

        if (status != null){
            wrapper.eq(Order::getStatus, status);
        }
        wrapper.orderByDesc(Order::getCreateTime);
        Page<Order> orderPage = this.page(new Page<>(page, size), wrapper);

        List<UserRechargeVO> finalList = Lists.newLinkedList();
        for (Order record : orderPage.getRecords()) {
            User user = userService.getById(record.getUserId());
            UserRechargeVO vo = new UserRechargeVO();
            if (user== null){
                vo.setNickname("用户已注销");
                vo.setUserId(null);
            }else {
                vo.setNickname(user.getNickname());
                vo.setUserId(user.getAccount());
            }

            if (StringUtils.isNotBlank(record.getAppStoreProductId())){
                vo.setType("苹果支付");
            }else if ("alipay".equals(record.getType())){
                vo.setType("支付宝支付");
            }else {
                vo.setType("微信支付");
            }
            vo.setOrderNo(record.getOrderNo());

            vo.setPrice(record.getTotalPrice().doubleValue());
            Integer orderStatus = record.getStatus();
            if (orderStatus == 0){
                vo.setStatus("未支付");
            }else if (orderStatus == 1){
                vo.setStatus("支付成功");
            }else {
                vo.setStatus("支付失败");
            }

            vo.setCreateTime(record.getCreateTime());
            finalList.add(vo);
        }

        IPage<UserRechargeVO> finalPage = new Page<>();
        finalPage.setSize(orderPage.getSize());
        finalPage.setPages(orderPage.getPages());
        finalPage.setTotal(orderPage.getTotal());
        finalPage.setRecords(finalList);
        return finalPage;
    }

}
